package org.ihelpuoo.orm.handler.dom;

import java.util.ArrayList;
import java.util.List;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;

import org.ihelpuoo.orm.filter.Filter;
import org.ihelpuoo.orm.handler.dom.EleReadArrayFieldHandler;
import org.ihelpuoo.orm.handler.dom.EleReadObjectFieldHandler;
import org.ihelpuoo.orm.handler.dom.EleReadListFieldHandler;
import org.ihelpuoo.orm.handler.dom.EleReadMapFieldHandler;
import org.ihelpuoo.orm.handler.dom.EleReadNormalFieldHandler;
import org.ihelpuoo.orm.handler.dom.EleSaveArrayFieldHandler;
import org.ihelpuoo.orm.handler.dom.EleSaveObjectFieldHandler;
import org.ihelpuoo.orm.handler.dom.EleSaveListFieldHandler;
import org.ihelpuoo.orm.handler.dom.EleSaveMapFieldHandler;
import org.ihelpuoo.orm.handler.dom.EleSaveNormalFieldHandler;
import org.ihelpuoo.orm.filter.FieldFilter;
import org.ihelpuoo.orm.handler.FieldHandlers;
import org.ihelpuoo.orm.handler.LoopScope;
import org.ihelpuoo.orm.handler.MicroObjectProcessor;
import org.ihelpuoo.orm.IIIException;
import org.ihelpuoo.orm.IIIManual;
import org.ihelpuoo.orm.ObjectRule;
import org.ihelpuoo.util.Pager;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * <b>DocumentBeanHandler class:</b>
 * <hr color=grey size=1>
 *
 *
 *
 * @author zozoh  created @ 2007
 *
 */
public class ElementProcessor extends MicroObjectProcessor
{

	public ElementProcessor(IIIManual manual)
	{
		super(manual);
		this.getFieldHandlers = new FieldHandlers(new EleReadNormalFieldHandler(this),
				new EleReadListFieldHandler(this),new EleReadArrayFieldHandler(this),
				new EleReadMapFieldHandler(this),new EleReadObjectFieldHandler(this));
		this.setFieldHandlers = new FieldHandlers(new EleSaveNormalFieldHandler(this),
				new EleSaveListFieldHandler(this),new EleSaveArrayFieldHandler(this),
				new EleSaveMapFieldHandler(this),new EleSaveObjectFieldHandler(this));
	}

	@Deprecated
	@Override
	public boolean delete(ObjectRule r, Object src, Object obj, FieldFilter ignore) throws IIIException
	{
		throw new IIIException(this.getClass().getName() + " do not support deleteBean()!");
	}

	@Deprecated
	@Override
	public int delete(ObjectRule r, Object src, List list, int off, int len) throws IIIException
	{
		throw new IIIException(this.getClass().getName() + " do not support clearBeans()!");
	}

	/**
	 * Add a new element as (Element)src 's last child 
	 * 
	 * @param src: Element object.
	 */
	@Override
	public Object insert(ObjectRule r, Object src, Object obj, FieldFilter actived,
			FieldFilter locked) throws IIIException
	{
		String tagName = r.getTagName();
		Node ele;
		if (src instanceof Document)
		{
			ele = ((Document)src).createElement(tagName);
		}
		else
		{
			ele = ((Node)src).getOwnerDocument().createElement(tagName);
		}
		((Node)src).appendChild(ele);
		this.update(r,ele,obj,actived,locked);
		return obj;
	}

	/**
	 * Query a group bean from a Document object. It will query each Node
	 * delcared by BenaFilter.
	 * 
	 * @see www.w3c.org
	 * @see org.ihelpuoo.orm.Bean
	 * @see org.ihelpuoo.orm.rule.BeanRule
	 * @see org.ihelpuoo.orm.filter.FieldFilter
	 * @param br: BeanRule
	 * @param doc: the Document object
	 * @param filter: should be a DOMBeanFilter instance
	 * @param actived: Which fields should be highlight.
	 * @param locked: Which fileds shoudl be ignore.
	 * @param pager: indicate the how many beans it want
	 * @return List object
	 * @throws IIIException
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List query(ObjectRule r, Object src, Class beanType, Filter filter,
			FieldFilter actived, FieldFilter locked, Pager pager, Object refer)
			throws IIIException
	{
		NodeList children;
		XPath xpath = this.manual.xpath().newXPath();
		try
		{
			if (null == filter)
			{
				String tagName = r.getTagName();
				children = (NodeList)xpath.evaluate("./" + tagName,src,XPathConstants.NODESET);
			}
			else
			{
				children = (NodeList)xpath.evaluate(filter.getString(),src,
						XPathConstants.NODESET);
			}
			LoopScope ls = LoopScope.evaluate(pager,children.getLength());
			List list = new ArrayList(ls.max - ls.start);
			for (int i = ls.start; i < ls.max; i++)
			{
				Object b = beanType.newInstance();
				b = fetch(r,children.item(i),b,actived,locked, null);
				list.add(b);
			}
			return list;
		}
		catch (Exception e)
		{
			throw IIIException.wrap(e);
		}
	}
}
